<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>

    /* 
  - 变量到底是什么?
    - 可以变化的量, 由变量名和变量值组成, 名称是标识, 值是可以变化的
    - 一个变量对应一块小内存, 变量名是这块内存的标识名称, 用于查找这块内存, 变量的值就是内存中保存的数据
  - 基本类型变量与引用类型变量的区别是什么?
    - 根据变量内存中保存的数据来区分
    - 基本类型变量: 内存中保存的基本类型的数据
    - 引用类型变量: 内存中保存的是地址值
  - 给变量赋值到底做了什么?
    - 将基本类型数据赋给变量: 将数据保存在变量内存中
    - 将对象赋给变量: 将对象在内存中的地址值保存在变量内存中
    - 将另一个变量赋给变量: 将右侧变量内存中的数据(基本数据/地址值数据)拷贝保存到左侧变量内存
  - 函数传参, 到底是值传递还是引用传递? 
    - 函数调用时, 是将实参变量的数据拷贝一份赋值给形参变量
    - 只是实参变量数据可能是基本类型, 也可能是引用类型的(地址值)
  - 有哪些改变变量值的方式?
    - 只能通过赋值改变
    - c.m = 2: 改的是c变量指向的对象内部的属性数据, c本身没有变化的(对象内存的位置没变)
  - 如何理解下面2句重要的话(编码演示说明)?
    - 2个引用变量指向同一个对象, 如果通过一个变量修改对象内部的数据 => 另一个变量也能看到原对象(新数据)
    - 2个引用变量指向同一个对象, 让其中一个变量指向一个新的对象 => 另一个引用变量看到的是老的对象
  */

  var a1 = 2
  var a2 = {}
   /*
    正确： 将a1中保存的2拷贝一份， 保存到a3的内存中
  */
  var a3 = a1
  /* 错误： a2 的地址值 又赋值给了 a4 
    正确： 将a2中保存的地址值拷贝一份， 保存到a4的内存中
  */
  var a4 = a2  
  /* 
  var a = b: 拷贝b内存中保存的数据， 保存到a内存中
  */

  /* 
  函数传参, 到底是值传递还是引用传递? 
    都是值传递： 无论实参变量是什么类型， 都是拷贝实参变量中的数据值（基本/地址值）赋值给形参变量
    如果将传递地址值理解为引用传递， 那当实参蛮是引用类型时，就是引用传递
  */
    var a = 3
    a = {m: 1}
    function fn(b) {  // b = a
      
    }
    fn(a)
    /* 
    有哪些改变变量值的方式?   重新赋值
    */
    // a = []
    a.m = 3 // 有没有改变变量a

    /* 
    - 如何理解下面2句重要的话(编码演示说明)?
    - 2个引用变量指向同一个对象, 如果通过一个变量修改对象内部的数据 => 另一个变量也能看到原对象(新数据)
    - 2个引用变量指向同一个对象, 让其中一个变量指向一个新的对象 => 另一个引用变量看到的是老的对象
    */

    var o1 = {m: 1}
    var o2 = o1
    // o2.m = 2
    // console.log(o1.m) // 2
    // o1 = {m: 2}
    // console.log(o2.m)  // 1

    function fn (o1) {
      // o1 = {m: 2}
      o1.m = 3
    }
    fn(o1)
    console.log(o1.m, o2.m) // ? ?


    /* 
    查找a: 查找变量, 沿着作用域链查找
      * 找不到 => 报错(ReferenceError/引用错误 ): a is not defined
      * 找到了: 得到a的值, 准备去.b, 但a的值不同, 处理结果不同
        * undefined/null  ==> 报错(TypeError/类型错误): 
                    can not read property b of undefined/null
        * boolean/number/string基本值  ==> 创建一个包含这个值的对应的包装类型对象
        * Boolean/Number/String
        * 引用地址值 ==> 找到对应的对象 ==> 准备找b
        
    查找b属性: 先在对象自身上找, 如果没找到, 沿着原型链查找
      * 找不到: 返回undefined
      * 找到了, 返回它的值(值的拷贝)
    */
    var a = 1
    console.log(a.b) // new Number(a).b
  
  </script>
</body>
</html>